﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; 
using System.Net;
using System.Net.Sockets;
using System.Threading;


namespace MonitorEquipmentFrm
{
    public class clsCommon
    {  
        public static string GetServerIp(string str)
        {
            string[] R = str.Split(new char[] { ';', ';', ';', ';' });

            string sIP = R[1].Substring(R[1].IndexOf("=") + 1, (R[1].Length - 1 - R[1].IndexOf("=")));
            string sPort = R[4].Substring(R[4].IndexOf("=") + 1, (R[4].Length - 1 - R[4].IndexOf("=")));            

            return sIP; 
        }
        public static string GetServerPort(string str)
        {
            string[] R = str.Split(new char[] { ';', ';', ';', ';' });

            string sIP = R[1].Substring(R[1].IndexOf("=") + 1, (R[1].Length - 1 - R[1].IndexOf("=")));
            string sPort = R[4].Substring(R[4].IndexOf("=") + 1, (R[4].Length - 1 - R[4].IndexOf("=")));            

            return sPort;
        }

        //进制转换
        public static string ConvertString(string value, int fromBase, int toBase)
        {
            int intValue = Convert.ToInt32(value, fromBase);
            return Convert.ToString(intValue, toBase);
        }



        /// <summary>
        /// <函数：Encode>
        /// 作用：将字符串内容转化为16进制数据编码，其逆过程是Decode
        /// 参数说明：
        /// strEncode 需要转化的原始字符串
        /// 转换的过程是直接把字符转换成Unicode字符,比如数字"3"-->0033,汉字"我"-->U+6211
        /// 函数decode的过程是encode的逆过程.
        /// </summary>
        /// <param name="strEncode"></param>
        /// <returns></returns>
        public static string Encode(string strEncode)
        {
            string strReturn = "";//  存储转换后的编码
            foreach (short shortx in strEncode.ToCharArray())
            {
                strReturn += shortx.ToString("X4");
            }
            return strReturn;
        }


        /// <summary>
        /// <函数：Decode>
        /// 作用：将16进制数据编码转化为字符串，是Encode的逆过程
        /// </summary>
        /// <param name="strDecode"></param>
        /// <returns></returns>
        public static string Decode(string strDecode)
        {
            string sResult = "";
            for (int i = 0; i < strDecode.Length / 4; i++)
            {
                sResult += (char)short.Parse(strDecode.Substring(i * 4, 4), global::System.Globalization.NumberStyles.HexNumber);
            }
            return sResult;
        }

        //字符串转为二进制
        public static String StringToBinary(string str)
        {
            byte[] data = Encoding.Default.GetBytes(str);
            StringBuilder strResult = new StringBuilder(data.Length * 8);

            foreach (byte b in data)
            {
                strResult.Append(Convert.ToString(b, 2).PadLeft(8, '0'));
            }
            return  strResult.ToString(); 
        }

        //位数补齐
        public static string SetBitNum(string str, int i)
        {
            int j = str.Length;
            string s = "";
            for (int k = 0; k < i - j; k++)
            {
                s = s + "0";
            }
            return str = s + str;
        }
        //************************************************RFID 存储格式********************************************
        //存储内容 	起始地址 	终止地址 	长度 	备  注 
        //行业标识 	1	8	8bits 	　 
        //馆代码 	9	24	16bits 	　 
        //馆藏代码 	25	32	8bits 	　 
        //标签类型 	33	34	2bits 	00：图书标签，01：架标,10：层标 				
        //流通标识 	35	35	1bits 	1:可流通，0：不可流通 
        //馆藏流水号 	36	80	45bits 	财产号，图书唯一码 
        //保留字段 	81	90	10bits 	保留(预留为分拣线使用) 
        //标签格式版本 	91	94	4bits 	 0~F(版本号为2) 修改：借与还状态92-93bit为防盗位
        //EAS防盗位 	95	96	2bits 	表示图书借还状态，00表示已借出，01表示未借出 
        //************************************************RFID 存储格式********************************************
        public static string GetNewRFID(string libNum, string tagType, string MaxID)
        {
            string sbussinessTag = "00000000";//8bits 
            string slibNum = clsCommon.SetBitNum(clsCommon.ConvertString(libNum, 10, 2), 16);//16bits  10进制的代码，转换为2进制，然后补齐16位bit
            string slibCNum = "00000000";//8bits 
            string stagType = tagType;//2bits 	00：图书标签，01：架标,10：层标 
            string sUse = "1";//1bits 	1:可流通，0：不可流通 
            string slibID = clsCommon.SetBitNum(StringToBinary(MaxID), 48);//45bits 	财产号，图书唯一码 
            string sReserved = "0000000";//7bits 	保留(预留为分拣线使用) 
            string sTagVer = "0001";//4bits 	{ 原来：0~F(版本号为2)}  修改：借与还状态92-93bit为防盗位 00表示已借出，01表示未借出
            string sEAS = "01";//2bits 	表示图书借还状态，00表示已借出，01表示未借出

            string sNewRFID = sbussinessTag + slibNum + slibCNum + stagType + sUse + slibID + sReserved + sTagVer + sEAS;
           
            string strTemp = "";
            for (int m = 0; m < sNewRFID.Length / 4; m++)
            {
                string s = sNewRFID.Substring(m * 4, 4);
                strTemp += clsCommon.ConvertString(s, 2, 16) ;
            }
            sNewRFID = strTemp.ToUpper();
            //sNewRFID = clsCommon.ConvertString(sNewRFID, 2, 16);//bit位转换为16进制，方便写入标签
            return sNewRFID;

        }
        //根据RFID编码，判断是什么类型的标签 00：图书标签，01：架标,10：层标
        public static string GetRFIDType(string sRFID)
        {
            string sHex = "";
            string s = "";
            for (int i = 0; i < sRFID.Length; i++)
            {
                s = sRFID.Substring(i, 1);
                sHex +=clsCommon.SetBitNum(clsCommon.ConvertString(s, 16, 2),4); 
            }
            s = sHex.Substring(32, 2);
            return s;
        }

        public class StateObject
        {// Client socket.
            public Socket workSocket = null;// Size of receive buffer.
            public const int BufferSize = 256;// Receive buffer.
            public byte[] buffer = new byte[BufferSize];// Received data string.
            public StringBuilder sb = new StringBuilder();
        }
        public const int port = 5000;// ManualResetEvent instances signal completion.
        public static ManualResetEvent connectDone = new ManualResetEvent(false);
        public static ManualResetEvent sendDone = new ManualResetEvent(false);
        public static ManualResetEvent receiveDone = new ManualResetEvent(false);// The response from the remote device.
        public static String response = String.Empty;

        //C# Socket异步通讯客户端之连接部分Callback:

        public static void ConnectCallback(IAsyncResult ar)
        {
            // 从state对象获取socket. 

            Socket client1 = (Socket)ar.AsyncState;   // 完成连接.    
            client1.EndConnect(ar);
            Console.WriteLine("Socket connected to {0}", client1.RemoteEndPoint.ToString());
            // 连接已完成，主线程继续.  
            connectDone.Set();
        }
        //C# Socket异步通讯客户端之数据接收：


        public static void Receive(Socket client)
        {   // 构造容器state.  
            StateObject state = new StateObject();
            state.workSocket = client;   // 从远程目标接收数据. 
            //client.ReceiveTimeout = 30000;
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);

        }

        public static void ReceiveCallback(IAsyncResult ar)
        {   // 从输入参数异步state对象中获取state和socket对象 
            StateObject state = (StateObject)ar.AsyncState;
            Socket client1 = state.workSocket;   //从远程设备读取数据
            int bytesRead = client1.EndReceive(ar);
            if (bytesRead > 0)
            {  // 有数据，存储.  
                state.sb.Append(Encoding.GetEncoding("GBK").GetString(state.buffer, 0, bytesRead));
                //sRec = state.sb.ToString();
                response = state.sb.ToString();
                receiveDone.Set();
                // 继续读取. 
                // client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,  new AsyncCallback(ReceiveCallback), state);
            }
            else
            {  // 所有数据读取完毕. 
                if (state.sb.Length > 1)
                {
                    response = state.sb.ToString();
                }
                // 所有数据读取完毕的指示信号.  
                receiveDone.Set();
            }
        }
        //C# Socket异步通讯客户端之发送数据：


        public static void Send(Socket client, String data)
        {  // 格式转换.  
            byte[] byteData = Encoding.GetEncoding("GBK").GetBytes(data);
            // 开始发送数据到远程设备.
            //client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, byteData.Length);
            client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
        }

        public static void SendCallback(IAsyncResult ar)
        {   // 从state对象中获取socket 
            Socket client1 = (Socket)ar.AsyncState;
            // 完成数据发送. 
            int bytesSent = client1.EndSend(ar);
            Console.WriteLine("Sent {0} bytes to server.", bytesSent);
            // 指示数据已经发送完成，主线程继续.  
            sendDone.Set();
        }
       

    }
}
